package edu.pku.sei.transformation.qvt.codegen;

import edu.pku.sei.transformation.qvt.rule.*;

public class QVTGenerator
{
  protected static String nl;
  public static synchronized QVTGenerator create(String lineSeparator)
  {
    nl = lineSeparator;
    QVTGenerator result = new QVTGenerator();
    nl = null;
    return result;
  }

  public final String NL = nl == null ? (System.getProperties().getProperty("line.separator")) : nl;
  protected final String TEXT_1 = "transformation ";
  protected final String TEXT_2 = " (";
  protected final String TEXT_3 = "; ";
  protected final String TEXT_4 = ":";
  protected final String TEXT_5 = ":";
  protected final String TEXT_6 = ") {";
  protected final String TEXT_7 = NL + "\tkey ";
  protected final String TEXT_8 = "::";
  protected final String TEXT_9 = "{";
  protected final String TEXT_10 = ", ";
  protected final String TEXT_11 = "};";
  protected final String TEXT_12 = NL;
  protected final String TEXT_13 = NL + "\t\t";
  protected final String TEXT_14 = NL;
  protected final String TEXT_15 = NL + "\t";
  protected final String TEXT_16 = "top ";
  protected final String TEXT_17 = "relation ";
  protected final String TEXT_18 = " {\t";
  protected final String TEXT_19 = "\t\t" + NL + "\t\t";
  protected final String TEXT_20 = NL + "\t\t";
  protected final String TEXT_21 = "enforce";
  protected final String TEXT_22 = "checkonly";
  protected final String TEXT_23 = " domain ";
  protected final String TEXT_24 = " ";
  protected final String TEXT_25 = ";";
  protected final String TEXT_26 = NL + "\t\tprimitive domain ";
  protected final String TEXT_27 = " : ";
  protected final String TEXT_28 = ";";
  protected final String TEXT_29 = NL + "\t\twhen {";
  protected final String TEXT_30 = NL + "\t\t\t";
  protected final String TEXT_31 = NL + "\t\t}";
  protected final String TEXT_32 = NL + "\t\twhere {";
  protected final String TEXT_33 = NL + "\t\t\t";
  protected final String TEXT_34 = NL + "\t\t}" + NL + "\t}";
  protected final String TEXT_35 = NL;
  protected final String TEXT_36 = NL + "}";

  public String generate(Object argument)
  {
    final StringBuffer stringBuffer = new StringBuffer();
    ITransformation transformation = (ITransformation) argument;
    stringBuffer.append(TEXT_1);
    stringBuffer.append(transformation.getName());
    stringBuffer.append(TEXT_2);
    //transformation parameters start
	for(int i = 0; i < transformation.getTypedModel().size(); i++) {
		ITypedModel param = transformation.getTypedModel().get(i);
		if (i != 0) {

    stringBuffer.append(TEXT_3);
    stringBuffer.append(param.getName());
    stringBuffer.append(TEXT_4);
    stringBuffer.append(param.getMetaModelName());
    
		} else {

    stringBuffer.append(param.getName());
    stringBuffer.append(TEXT_5);
    stringBuffer.append(param.getMetaModelName());
    
		}
	}
//transformation parameters end
    stringBuffer.append(TEXT_6);
    //transformation body start
	
	//key start
	for(int i=0; i < transformation.getKeys().size(); i++) {
		IKey key = transformation.getKeys().get(i);

    stringBuffer.append(TEXT_7);
    stringBuffer.append(key.getMetaModelName());
    stringBuffer.append(TEXT_8);
    stringBuffer.append(key.getClassName());
    stringBuffer.append(TEXT_9);
    
		for(int j=0; j<key.getAttributes().size(); j++) {
			if (j == 0){
			
    stringBuffer.append(key.getAttributes().get(j).toString());
    
			} else {
			
    stringBuffer.append(TEXT_10);
    stringBuffer.append(key.getAttributes().get(j).toString());
    
			}
		}
		
    stringBuffer.append(TEXT_11);
    
	}
	//key end

    stringBuffer.append(TEXT_12);
    
	for(String s : transformation.getQuerys()) {

    stringBuffer.append(TEXT_13);
    stringBuffer.append(s);
    
	}

    stringBuffer.append(TEXT_14);
    
	//relations start
	for(int i = 0; i < transformation.getRelation().size(); i++) {
		IRelation relation = transformation.getRelation().get(i);		

    stringBuffer.append(TEXT_15);
    if(relation.isTopLevel()){
    stringBuffer.append(TEXT_16);
    }
    stringBuffer.append(TEXT_17);
    stringBuffer.append(relation.getName());
    stringBuffer.append(TEXT_18);
    
		//variable start
		for (String s : relation.getVariables()) {

    stringBuffer.append(TEXT_19);
    stringBuffer.append(s);
    
		}
		//variable end
		//domain start
		for(IDomain domain : relation.getDomains()) {

    stringBuffer.append(TEXT_20);
    if (domain.isEnforce()){
    stringBuffer.append(TEXT_21);
    }else{
    stringBuffer.append(TEXT_22);
    }
    stringBuffer.append(TEXT_23);
    stringBuffer.append(domain.getTypedModelName());
    stringBuffer.append(TEXT_24);
    stringBuffer.append(domain.getRootElement().getContent());
    stringBuffer.append(TEXT_25);
    
		}
		for(IPrimitiveDomain domain: relation.getPrimitiveDomains()) {

    stringBuffer.append(TEXT_26);
    stringBuffer.append(domain.getName());
    stringBuffer.append(TEXT_27);
    stringBuffer.append(domain.getTypeName());
    stringBuffer.append(TEXT_28);
    
		}
		//domain end
		//when start

    stringBuffer.append(TEXT_29);
    for (String s : relation.getWhen()) {
    stringBuffer.append(TEXT_30);
    stringBuffer.append(s);
    }
    stringBuffer.append(TEXT_31);
    
		//when end

    stringBuffer.append(TEXT_32);
    for (String s : relation.getWhere()) {
    stringBuffer.append(TEXT_33);
    stringBuffer.append(s);
    }
    stringBuffer.append(TEXT_34);
    
	}
	//relation end

    stringBuffer.append(TEXT_35);
    //transformation body end
    stringBuffer.append(TEXT_36);
    return stringBuffer.toString();
  }
}
